# -*- coding: utf-8 -*-

import json
from datetime import datetime, timedelta

from common.admin import db as user_db
from common.order import admin_db as order_admin_db
from common.order import db as order_db
from common.order_inquiry import admin_db as order_inquiry_db
from common.order_inquiry import handler as order_inquiry_handler
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.api import token_required
from common.utils.decorator import response_wrapper
from common.utils.tz import (
    utc_to_local_str
)
from django.utils.decorators import method_decorator
from django.utils.encoding import smart_unicode
from django.views.generic import TemplateView

_LOGGER = track_logging.getLogger(__name__)


class OrderInquiryView(TemplateView):
    def get(self, req):
        query_dct = req.GET.dict()

        cond = user_db.get_mchids_filter_by_user(req.user_id)
        if cond and not query_dct.get('mch_id', ''):
            query_dct['mch_id'] = cond

        if query_dct.get('created_at', None) is None and query_dct.get('updated_at', None) is None:
            tmp_time = datetime.utcnow() + timedelta(days=-30)
            query_dct['created_at'] = {"$gte": tmp_time.strftime("%Y-%m-%d %H:%M:%S")}

        items, total_count = order_inquiry_db.list_order(query_dct)

        resp_items = []
        for item in items:
            data = item.as_dict()
            data['processing_time'] = utc_to_local_str(data['processing_time'])
            data['created_at'] = utc_to_local_str(data['created_at'])
            data['confirmed_at'] = utc_to_local_str(data['confirmed_at'])
            data['updated_at'] = utc_to_local_str(data['updated_at'])
            data['notified_at'] = utc_to_local_str(data['notified_at'])
            data['selected'] = False
            data['receipt'] = order_inquiry_handler.get_receipt(data['receipt'])
            resp_items.append(data)

        return {'list': resp_items, 'page': query_dct.get('$page', 1),
                'size': len(resp_items), 'total_count': total_count}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(OrderInquiryView, self).dispatch(*args, **kwargs)


class SingleOrderInquiryView(TemplateView):
    def get(self, req, order_inquiry_id):
        order_inquiry = order_inquiry_db.get_order(id=int(order_inquiry_id))
        data = order_inquiry.as_dict()
        data['id'] = order_inquiry_id
        data['processing_time'] = utc_to_local_str(data['processing_time'])
        data['created_at'] = utc_to_local_str(data['created_at'])
        data['confirmed_at'] = utc_to_local_str(data['confirmed_at'])
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        data['notified_at'] = utc_to_local_str(data['notified_at'])
        return data

    def post(self, req, order_inquiry_id):
        _LOGGER.info('update order inquiry: %s', req.body)

        order_exists = order_inquiry_db.get_order(order_inquiry_id)
        if not order_exists:
            raise err.ResourceNotFound('order_inquiry_id {} not found'.format(order_inquiry_id))

        query_dct = json.loads(smart_unicode(req.body))
        existing_pay_order = order_db.get_order(order_exists.mch_id, order_exists.out_trade_no)
        if existing_pay_order:
            existing_pay_order.order_inquiry_status = query_dct['status']
        if 'status' in query_dct:
            if query_dct['status'] == order_inquiry_db.INQUIRY_STATUS.PROCESSING:
                query_dct['operator'] = req.user.nickname
                query_dct['processing_time'] = datetime.utcnow()
            if query_dct['status'] in [order_inquiry_db.INQUIRY_STATUS.SUCCESS, order_inquiry_db.INQUIRY_STATUS.FAILED]:
                query_dct['confirmed_at'] = datetime.utcnow()
        order_inquiry_db.upsert_order(query_dct, int(order_inquiry_id))
        order_admin_db.upsert_order(existing_pay_order.as_dict(), int(existing_pay_order.id))
        if 'status' in query_dct and \
            query_dct['status'] in [order_inquiry_db.INQUIRY_STATUS.SUCCESS, order_inquiry_db.INQUIRY_STATUS.FAILED]:
            return self.put(req, order_inquiry_id)
        else:
            return {}

    def put(self, req, order_inquiry_id):
        _LOGGER.info('push order inquiry: %s', order_inquiry_id)

        order_inquiry = order_inquiry_db.get_order(order_inquiry_id)
        if not order_inquiry:
            raise err.ResourceNotFound('order_inquiry_id {} not found'.format(order_inquiry_id))

        notify_status = order_inquiry_db.INQUIRY_NOTIFY_STATUS.FAILED
        if order_inquiry_handler.check_valid_order(order_inquiry,
                                                   order_inquiry_handler.ORDER_INQUIRY_NOT_FINISHED,
                                                   msg='order_inquiry_id {} is still'.format(order_inquiry_id)):
            notify_status = order_inquiry_handler.notify(order_inquiry)

        _LOGGER.info('push order_id: %s', order_inquiry_id)
        return {'result': 'ok', 'id': order_inquiry_id, 'notify_status': notify_status}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(SingleOrderInquiryView, self).dispatch(*args, **kwargs)
